package com.example.rocketmq.config;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * Sentinel 配置类
 * 配置限流规则，实现匀速消费
 *
 * @author demo
 */
@Slf4j
@Component
public class SentinelConfig {

    @Autowired
    private RocketMQProperties properties;

    @PostConstruct
    public void init() {
        initFlowRules();
    }

    /**
     * 初始化限流规则
     * 使用匀速器模式，实现消息的匀速消费
     */
    private void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();

        // 创建限流规则
        FlowRule rule = new FlowRule();

        // 资源名称：消息消费限流
        rule.setResource("messageConsume");
        // 限流类型：QPS限流
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);

        // 限流阈值：每分钟消费的消息数量
        int messagesPerMinute = properties.getConsumer().getRateLimit().getMessagesPerMinute();
        double qps = messagesPerMinute / 60.0; // 转换为每秒QPS

        rule.setCount(qps);

        // 限流模式：匀速器模式（削峰填谷）
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);

        // 预热时间：1秒
        rule.setWarmUpPeriodSec(1);

        // 最大排队等待时间：5秒
        rule.setMaxQueueingTimeMs(5000);

        rules.add(rule);

        // 加载规则
        FlowRuleManager.loadRules(rules);

        log.info("Sentinel 限流规则初始化完成 - 资源: {}, QPS: {}, 模式: 匀速器",
                rule.getResource(), qps);
    }

    /**
     * 动态更新限流规则
     *
     * @param messagesPerMinute 每分钟消费消息数量
     */
    public void updateFlowRule(int messagesPerMinute) {
        List<FlowRule> rules = new ArrayList<>();

        FlowRule rule = new FlowRule();
        rule.setResource("messageConsume");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);

        double qps = messagesPerMinute / 60.0;
        rule.setCount(qps);
        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
        rule.setWarmUpPeriodSec(1);
        rule.setMaxQueueingTimeMs(5000);

        rules.add(rule);

        FlowRuleManager.loadRules(rules);

        log.info("Sentinel 限流规则已更新 - QPS: {}", qps);
    }
}
